home *** CD-ROM | disk | FTP | other *** search
- * $Id: lostly sensible, .1 1999/08/19 14:17:37 lhecking Exp $
- /* GNUPLOT - latex.trm */
- * Copyright 1990 - 1993, 1998
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- * This file is included by ../term.c.
- * This terminal driver supports:
- * LaTeX pictures (latex).
- * LaTeX pictures with emTeX specials (emtex).
- * AUTHORS
- * David Kotz, Russell Lang
- * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
- /* modified to optimize use of \rule for long lines */
- /* TLDC: modified to have nice line types */
- /* the following LATEX driver has been modified by
- Russell Lang, eln272v@monu1.cc.monash.oz from the
- GnuTeX 1.3 driver by David Kotz, David.Kotz@Dartmouth.edu.
- Since then it has been further extended by David Kotz.
- EmTeX driver by Russell Lang. */
- /* 9 Dec 1992 LATEX_put_text rewritten to handle \\ newlines
- Daniel S. Lewart (d-lewart@uiuc.edu) */
- /* Since it took me a little while to figure out what is happening,
- * I may as well write it down.
- * There are three length scales of interest: inches, points
- * and dots. inches are obvious. points are the usual typesetting
- * thing (ie approx 72 points per inch). This driver works in
- * units of dots, which corresponds to pixels on a 300 DPI printer.
- * We do a \setlength{unitlength}{...pt} to make teX work in
- * terms of dots. The ... is called LATEX_UNIT in here.
- * The reason I had to get involved in all of this is because
- * font size (in pts) was not being scaled up by DOTS_PER_POINT
- * - drd, Sept 1996
- #include "driver.h"
- #ifdef TERM_REGISTER
- register_term(latex)
- #ifdef EMTEX
- register_term(emtex)
- #endif
- #endif
- #ifdef TERM_PROTO
- TERM_PUBLIC void LATEX_options __PROTO((void));
- TERM_PUBLIC void LATEX_init __PROTO((void));
- TERM_PUBLIC void LATEX_graphics __PROTO((void));
- TERM_PUBLIC void LATEX_text __PROTO((void));
- TERM_PUBLIC void LATEX_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
- TERM_PUBLIC void LATEX_linetype __PROTO((int linetype));
- TERM_PUBLIC void LATEX_move __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void LATEX_point __PROTO((unsigned int x, unsigned int y, int number));
- TERM_PUBLIC void LATEX_vector __PROTO((unsigned int ux, unsigned int uy));
- TERM_PUBLIC void LATEX_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, TBOOLEAN head));
- TERM_PUBLIC int LATEX_justify_text __PROTO((enum JUSTIFY mode));
- TERM_PUBLIC int LATEX_text_angle __PROTO((int ang));
- TERM_PUBLIC void LATEX_reset __PROTO((void));
- #ifdef EMTEX
- TERM_PUBLIC void EMTEX_init __PROTO((void));
- TERM_PUBLIC void EMTEX_reset __PROTO((void));
- TERM_PUBLIC void EMTEX_text __PROTO((void));
- #endif
- #ifdef EEPIC
- TERM_PUBLIC void EEPIC_move __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void EEPIC_vector __PROTO((unsigned int ux, unsigned int uy));
- #endif
- #define TINY_STEP 0.5 /* tiny steps for high quality lines */
- #define LATEX_PTS_PER_INCH (72.27)
- #define DOTS_PER_INCH (300) /* resolution of printer we expect to use */
- #define LATEX_UNIT (LATEX_PTS_PER_INCH/DOTS_PER_INCH) /* dot size in pt */
- /* 5 inches wide by 3 inches high (default) */
- #define LATEX_XMAX (5*DOTS_PER_INCH) /* (LATEX_PTS_PER_INCH/LATEX_UNIT*5.0) */
- #define LATEX_YMAX (3*DOTS_PER_INCH) /* (LATEX_PTS_PER_INCH/LATEX_UNIT*3.0) */
- #define LATEX_HTIC (5*DOTS_PER_INCH/72) /* (5 pts) */
- #define LATEX_VTIC (5*DOTS_PER_INCH/72) /* (5 pts) */
- #define LATEX_HCHAR (DOTS_PER_INCH*53/10/72) /* (5.3 pts) */
- #define LATEX_VCHAR (DOTS_PER_INCH*11/72) /* (11 pts) */
- #endif
- #ifndef TERM_PROTO_ONLY
- #ifdef TERM_BODY
- static int LATEX_posx;
- static int LATEX_posy;
- static int LATEX_fontsize = 10;
- static char LATEX_font[MAX_ID_LEN+1] = "cmr";
- static enum JUSTIFY latex_justify = LEFT;
- static int latex_angle = 0;
- /* Default line-drawing character */
- /* the definition of plotpoint varies with linetype */
- #define LATEX_DOT "\\usebox{\\plotpoint}"
- #define LATEX_TINY_DOT "\\rule{1pt}{1pt}" /* for dots plot style */
- /* POINTS */
- #define LATEX_POINT_TYPES 12 /* we supply more point types */
- static char GPFAR *GPFAR LATEX_points[] =
- "\\raisebox{-.8pt}{\\makebox(0,0){$\\Diamond$}}",
- "\\makebox(0,0){$+$}",
- "\\raisebox{-.8pt}{\\makebox(0,0){$\\Box$}}",
- "\\makebox(0,0){$\\times$}",
- "\\makebox(0,0){$\\triangle$}",
- "\\makebox(0,0){$\\star$}",
- "\\circle{12}", "\\circle{18}", "\\circle{24}",
- "\\circle*{12}", "\\circle*{18}", "\\circle*{24}"
- /* LINES */
- static float LATEX_size = 0; /* current thick of line in points */
- static float LATEX_dotspace = 0; /* current dotspace of line in points */
- #define LATEX_LINE_TYPES 6 /* number of line types below */
- #define LATEX_THIN_LINE 0 /* the thinnest solid line type */
- static struct {
- float size; /* size of dot, or thick of line in points */
- float dotspace; /* inter-dot space in points; 0 for lines */
- } GPFAR LATEX_lines[] =
- {0.4, 0.0}, /* thin solid line */
- {0.4, 5.0}, /* thin dotted line */
- {0.8, 0.0}, /* thick solid line */
- {1.0, 5.0}, /* thick dotted line */
- {1.2, 0.0}, /* Thick solid line */
- {1.0, 10.0}, /* thick widely dotted line */
- /* for drawing dotted and solid lines */
- static void LATEX_dot_line __PROTO((int x1, int x2, int y1, int y2));
- static void LATEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
- static void LATEX_rule __PROTO((int code, double x, double y, double width, double height));
- static void LATEX_flushdot __PROTO((void));
- #define LATEX_flushrule() LATEX_rule(2, 0.,0.,0.,0.) /* flush old rule */
- static TBOOLEAN LATEX_moved = TRUE; /* pen is up after move */
- static float LATEX_dotsize; /* size of LATEX_DOT in units */
- static TBOOLEAN LATEX_needsdot = FALSE; /* does dotted line need termination? */
- #ifdef EMTEX
- TBOOLEAN emtex = FALSE; /* not currently using emtex */
- static void
- EMTEX_solid_line __PROTO((int x1, int x2, int y1, int y2));
- #endif
- /* ARROWS */
- /* the set of non-vertical/non-horizontal LaTeX vector slopes */
- /* except negatives - they are handled specially */
- static struct vslope {
- int dx, dy;
- } GPFAR LATEX_slopes[] =
- {1, 1},
- {1, 2},
- {1, 3},
- {1, 4},
- {2, 1},
- {2, 3},
- {3, 1},
- {3, 2},
- {3, 4},
- {4, 1},
- {4, 3},
- {0, 0} /* terminator */
- /* figure out the best arrow */
- void best_latex_arrow __PROTO((int, int, int, int, int, TBOOLEAN));
- TERM_PUBLIC void LATEX_options()
- if (!END_OF_COMMAND) {
- if (almost_equals(c_token, "c$ourier")) {
- strcpy(LATEX_font, "cmtt");
- c_token++;
- } else if (almost_equals(c_token, "r$oman")) {
- strcpy(LATEX_font, "cmr");
- c_token++;
- } else if (almost_equals(c_token, "d$efault")) {
- strcpy(LATEX_font, "doc");
- c_token++;
- }
- if (!END_OF_COMMAND) {
- struct value a;
- LATEX_fontsize = (int) real(const_express(&a));
- }
- /* tell gnuplot core about char. sizes. Horizontal spacing
- * is about half the text pointsize
- */
- term->v_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 72);
- term->h_char = (unsigned int) (LATEX_fontsize * DOTS_PER_INCH / 144);
- if (strcmp(LATEX_font, "doc")==0)
- strncpy(term_options, "(document specific font)",MAX_LINE_LEN);
- else
- sprintf(term_options, "%s %d",
- LATEX_font[2] == 't' ? "courier" : "roman", LATEX_fontsize);
- TERM_PUBLIC void LATEX_init()
- #ifdef EMTEX
- emtex = FALSE;
- #endif
- LATEX_posx = LATEX_posy = 0;
- fprintf(gpoutfile, "\
- %% GNUPLOT: LaTeX picture\n\
- \\setlength{\\unitlength}{%fpt}\n\
- \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
- LATEX_UNIT);
- LATEX_linetype(-1);
- LATEX_size = 0;
- TERM_PUBLIC void LATEX_graphics()
- register struct termentry *t = term;
- /* bounding box */
- int xscale = xsize * t->xmax;
- int yscale = ysize * t->ymax;
- fprintf(gpoutfile, "\\begin{picture}(%d,%d)(0,0)\n", xscale, yscale);
- if (strcmp(LATEX_font, "doc") != 0) {
- fprintf(gpoutfile, "\
- \\font\\gnuplot=%s10 at %dpt\n\
- \\gnuplot\n",
- LATEX_font, LATEX_fontsize);
- }
- TERM_PUBLIC void LATEX_text()
- LATEX_flushrule();
- LATEX_flushdot();
- fputs("\\end{picture}\n", gpoutfile);
- LATEX_posx = LATEX_posy = 0; /* current position */
- LATEX_moved = TRUE; /* pen is up after move */
- TERM_PUBLIC void LATEX_linetype(linetype)
- int linetype;
- float size;
- if (linetype >= LATEX_LINE_TYPES)
- linetype %= LATEX_LINE_TYPES;
- #ifdef EMTEX
- if (!emtex)
- #endif
- LATEX_flushrule();
- LATEX_flushdot();
- /* Find the new desired line thickness. */
- /* negative linetypes (for axes) use a thin line */
- /* only relevant for drawing axes/border in 3d */
- size = (linetype >= 0 ? LATEX_lines[linetype].size
- : LATEX_lines[LATEX_THIN_LINE].size);
- /* If different from current size, redefine \plotpoint */
- if (size != LATEX_size) {
- fprintf(gpoutfile,
- "\\sbox{\\plotpoint}{\\rule[%.3fpt]{%.3fpt}{%.3fpt}}%%\n",
- -size / 2, size, size);
- #ifdef EMTEX
- if (emtex) /* change line width */
- fprintf(gpoutfile, "\\special{em:linewidth %.1fpt}%%\n", size);
- #endif
- }
- LATEX_size = size;
- LATEX_dotsize = size / LATEX_UNIT;
- LATEX_dotspace = (linetype >= 0) ? LATEX_lines[linetype].dotspace : 0;
- LATEX_moved = TRUE; /* reset */
- TERM_PUBLIC void LATEX_move(x, y)
- unsigned int x, y;
- LATEX_flushdot();
- LATEX_posx = x;
- LATEX_posy = y;
- LATEX_moved = TRUE; /* reset */
- TERM_PUBLIC void LATEX_point(x, y, number) /* version of line_and_point */
- unsigned int x, y;
- int number; /* type of point */
- LATEX_move(x, y);
- /* Print the character defined by 'number'; number < 0 means
- to use a dot, otherwise one of the defined points. */
- fprintf(gpoutfile, "\\put(%d,%d){%s}\n", x, y,
- (number < 0 ? LATEX_TINY_DOT
- : LATEX_points[number % LATEX_POINT_TYPES]));
- TERM_PUBLIC void LATEX_vector(ux, uy)
- unsigned int ux, uy;
- if (LATEX_dotspace == 0.0) {
- /* solid line */
- #ifdef EMTEX
- if (emtex)
- EMTEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
- else
- #endif
- LATEX_solid_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
- } else
- /* dotted line */
- LATEX_dot_line(LATEX_posx, (int) ux, LATEX_posy, (int) uy);
- LATEX_posx = ux;
- LATEX_posy = uy;
- static void LATEX_solid_line(x1, x2, y1, y2)
- int x1, x2, y1, y2;
- float slope;
- int inc;
- float dx, dy, x, y;
- float offset, length;
- int code; /* possibly combine with previous rule */
- /* we draw a solid line using the current line thickness (size) */
- /* we do it with lots of \\rules */
- if (x1 == x2 && y1 == y2) { /* zero-length line - just a dot */
- if (LATEX_moved) {
- LATEX_flushrule();
- /* plot a dot */
- fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
- } else {
- code = (LATEX_moved ? 0 : 1); /* no combine after move */
- LATEX_moved = FALSE;
- if (x1 == x2) /* vertical line - special case */
- LATEX_rule(code, (double) x1, (double) y1,
- LATEX_dotsize, (double) y2 - y1);
- else if (y1 == y2) /* horizontal line - special case */
- LATEX_rule(code, (double) x1, (double) y1, (double) x2 - x1,
- LATEX_dotsize);
- else {
- dx = (float) x2 - x1;
- dy = (float) y2 - y1;
- slope = dy / dx;
- if (ABS(slope) <= 1.0) {
- /* longer than high */
- x = GPMIN(ABS(dx), (0.25 + 1.0 / ABS(slope)) * LATEX_dotsize);
- offset = sign(dy) * GPMIN(LATEX_dotsize, ABS(dy));
- dy = dy - offset;
- length = x * LATEX_UNIT;
- inc = (x == ABS(dx) ? 1 : GPMAX(1, ABS(dy) / TINY_STEP + 0.5));
- if (inc == 1) {
- fprintf(gpoutfile, "\\put(%u,%.2f){\\rule{%.3fpt}{%.3fpt}}\n",
- (x2 >= x1 ? x1 : x2), ((float) y1 + y2 - LATEX_dotsize) / 2,
- length, LATEX_dotsize * LATEX_UNIT);
- } else {
- dy = dy / inc;
- dx = (dx - sign(dx) * x) / (inc - 1);
- fprintf(gpoutfile,
- "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
- (dx >= 0.0 ? (float) x1 : x1 - x),
- (float) y1 - (ABS(dy) - offset) / 2,
- dx, dy, inc, length, ABS(dy) * LATEX_UNIT);
- /* done with one section, now smooth it */
- x = x / 2;
- dx = sign(dx) * x;
- dx = (float) x2 - x1 - dx;
- dy = (float) y2 - y1;
- fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
- (dx >= 0.0 ? (float) x1 : x1 - x), (float) y1 - LATEX_dotsize / 2,
- dx, dy, x * LATEX_UNIT, LATEX_dotsize * LATEX_UNIT);
- LATEX_moved = TRUE;
- } else {
- /* higher than long */
- y = GPMIN(ABS(dy), (0.25 + ABS(slope)) * LATEX_dotsize);
- offset = sign(dx) * GPMIN(LATEX_dotsize, ABS(dx));
- dx = dx - offset;
- length = y * LATEX_UNIT;
- inc = (y == ABS(dy) ? 1 : GPMAX(1, ABS(dx) / TINY_STEP + 0.5));
- if (inc == 1) {
- fprintf(gpoutfile, "\\put(%.2f,%u){\\rule{%.3fpt}{%.3fpt}}\n",
- ((float) x1 + x2 - LATEX_dotsize) / 2, (y2 >= y1 ? y1 : y2),
- LATEX_dotsize * LATEX_UNIT, length);
- } else {
- dx = dx / inc;
- dy = (dy - sign(dy) * y) / (inc - 1);
- fprintf(gpoutfile,
- "\\multiput(%.2f,%.2f)(%.3f,%.3f){%u}{\\rule{%.3fpt}{%.3fpt}}\n",
- (float) x1 - (ABS(dx) - offset) / 2,
- (dy >= 0 ? (float) y1 : y1 - y),
- dx, dy, inc, ABS(dx) * LATEX_UNIT, length);
- /* done with one section, now smooth it */
- y = y / 2;
- dx = (float) x2 - x1;
- dy = sign(dy) * y;
- dy = (float) y2 - y1 - dy;
- fprintf(gpoutfile, "\\multiput(%.2f,%.2f)(%.3f,%.3f){2}{\\rule{%.3fpt}{%.3fpt}}\n",
- (float) x1 - LATEX_dotsize / 2, (dy >= 0.0 ? (float) y1 : y1 - y),
- dx, dy, LATEX_dotsize * LATEX_UNIT, y * LATEX_UNIT);
- LATEX_moved = TRUE;
- }
- }
- /* Draw a \rule. Width or height may be negative; we can correct.
- * The rule is never output immediately. The previous rule is output
- * as-is if code is 0, and the previous rule is
- * combined with the current rule (if possible) if code is 1.
- * The previous rule is output, and the new one ignored, if code is 2.
- static void LATEX_rule(code, x, y, width, height)
- int code; /* how do we treat this rule? */
- double x, y;
- double width;
- double height;
- static float lastx, lasty;
- static float lastw, lasth;
- static TBOOLEAN isvalid = FALSE; /* is 'last' data valid? */
- TBOOLEAN combine = (code == 1);
- TBOOLEAN flush = (code == 2);
- if (!flush)
- if (width == 0 || height == 0)
- return; /* ignore this rule */
- if (isvalid && combine) {
- /* try to combine new rule with old rule */
- if ((int) lastx == (int) x && lastw == width) { /* vertical rule */
- if (lasth * height >= 0) { /* same sign */
- lasth += height;
- return;
- }
- } else if ((int) lasty == (int) y && lasth == height) { /* horiz rule */
- if (lastw * width >= 0) { /* same sign */
- lastw += width;
- return;
- }
- /* oh well, output last and remember the new one */
- }
- if (isvalid) {
- /* output the rule */
- if (lastw < 0) {
- lastx += lastw;
- lastw = -lastw;
- if (lasth < 0) {
- lasty += lasth;
- lasth = -lasth;
- /* if very small use canned dot */
- if (lastw < LATEX_dotsize || lasth < LATEX_dotsize)
- fprintf(gpoutfile, "\\put(%.1f,%.1f){%s}\n",
- lastx, lasty, LATEX_DOT);
- else
- fprintf(gpoutfile, "\\put(%.1f,%.1f){\\rule[%.3fpt]{%.3fpt}{%.3fpt}}\n",
- lastx, lasty, -LATEX_dotsize * LATEX_UNIT / 2,
- lastw * LATEX_UNIT, lasth * LATEX_UNIT);
- }
- if (flush) {
- isvalid = FALSE;
- } else {
- lastx = x;
- lasty = y;
- lastw = width;
- lasth = height;
- isvalid = TRUE;
- }
- static void LATEX_dot_line(x1, x2, y1, y2)
- int x1, x2, y1, y2;
- static float LATEX_left; /* fraction of space left after last dot */
- /* we draw a dotted line using the current dot spacing */
- if (LATEX_moved)
- LATEX_left = 1.0; /* reset after a move */
- /* zero-length line? */
- if (x1 == x2 && y1 == y2) {
- if (LATEX_moved)
- /* plot a dot */
- fprintf(gpoutfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
- } else {
- float dotspace = LATEX_dotspace / LATEX_UNIT;
- float x, y; /* current position */
- float xinc, yinc; /* increments */
- float slope; /* slope of line */
- float lastx = -1; /* last x point plotted */
- float lasty = -1; /* last y point plotted */
- int numdots = 0; /* number of dots in this section */
- /* first, figure out increments for x and y */
- if (x2 == x1) {
- xinc = 0.0;
- yinc = (y2 - y1 > 0) ? dotspace : -dotspace;
- } else {
- slope = ((float) y2 - y1) / ((float) x2 - x1);
- xinc = dotspace / sqrt(1 + slope * slope) * sign(x2 - x1);
- yinc = slope * xinc;
- /* now draw the dotted line */
- /* we take into account where we last placed a dot */
- for (x = x1 + xinc * (1 - LATEX_left), y = y1 + yinc * (1 - LATEX_left);
- (x2 - x) * xinc >= 0 && (y2 - y) * yinc >= 0; /* same sign or zero */
- lastx = x, x += xinc,
- lasty = y, y += yinc)
- numdots++;
- if (numdots == 1)
- fprintf(gpoutfile, "\\put(%.2f,%.2f){%s}\n",
- lastx, lasty, LATEX_DOT);
- else if (numdots > 0)
- fprintf(gpoutfile, "\\multiput(%u,%u)(%.3f,%.3f){%u}{%s}\n",
- x1, y1, xinc, yinc, numdots, LATEX_DOT);
- /* how much is left over, as a fraction of dotspace? */
- if (xinc != 0.0) /* xinc must be nonzero */
- if (lastx >= 0)
- LATEX_left = ABS(x2 - lastx) / ABS(xinc);
- else
- LATEX_left += ABS(x2 - x1) / ABS(xinc);
- else if (lasty >= 0)
- LATEX_left = ABS(y2 - lasty) / ABS(yinc);
- else
- LATEX_left += ABS(y2 - y1) / ABS(yinc);
- }
- LATEX_needsdot = (LATEX_left > 0);
- LATEX_moved = FALSE;
- static void LATEX_flushdot()
- if (LATEX_needsdot)
- fprintf(gpoutfile, "\\put(%d,%d){%s}\n",
- LATEX_posx, LATEX_posy, LATEX_DOT);
- LATEX_needsdot = FALSE;
- TERM_PUBLIC void LATEX_arrow(sx, sy, ex, ey, head)
- unsigned int sx, sy, ex, ey;
- TBOOLEAN head;
- best_latex_arrow(sx, sy, ex, ey, 1, head);
- LATEX_posx = ex;
- LATEX_posy = ey;
- void best_latex_arrow(sx, sy, ex, ey, who, head)
- int sx, sy, ex, ey; /* start and end points */
- int who; /* 1=LATEX, 2=EEPIC */
- TBOOLEAN head;
- int dx = ex - sx;
- int dy = ey - sy;
- float m; /* slope of line */
- float arrowslope; /* slope of arrow */
- float minerror = 0; /* best-case error */
- struct vslope *slope; /* one of the slopes */
- struct vslope *bestslope; /* the slope with min error */
- /* We try to draw a real arrow (ie, \vector). If we can't get
- * a slope that is close, we draw a bent arrow.
- */
- if (dx == 0) {
- /* vertical arrow */
- fprintf(gpoutfile, "\\put(%d,%d){\\%s(0,%d){%d}}\n",
- sx, sy, head ? "vector" : "line",
- sign(ey - sy), ABS(ey - sy));
- } else if (dy == 0) {
- /* horizontal arrow */
- fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,0){%d}}\n",
- sx, sy, head ? "vector" : "line",
- sign(ex - sx), ABS(ex - sx));
- } else {
- /* Slanted arrow. We'll give it a try.
- * we try to find the closest-slope arrowhead.
- bestslope = NULL;
- minerror = 0; /* to shut up turbo C */
- m = ABS((float) dy / dx); /* the slope we want */
- for (slope = LATEX_slopes; slope->dx != 0.0; slope++) {
- /* find the slope of the arrow */
- arrowslope = (float) slope->dy / slope->dx;
- if (bestslope == NULL || ABS(m - arrowslope) < minerror) {
- minerror = ABS(m - arrowslope);
- bestslope = slope;
- }
- /* now we have the best slope arrow */
- /* maybe it's exactly the right slope! */
- if (minerror == 0.0) /* unlikely but possible */
- fprintf(gpoutfile, "\\put(%d,%d){\\%s(%d,%d){%d}}\n",
- sx, sy, head ? "vector" : "line",
- bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy),
- ABS(ex - sx));
- else {
- /* we draw the line the usual way, with thin lines */
- #ifdef EMTEX
- if (emtex) {
- LATEX_linetype(LATEX_THIN_LINE);
- EMTEX_solid_line(sx, ex, sy, ey);
- } else
- #endif
- if (who == 1) {
- LATEX_linetype(LATEX_THIN_LINE);
- LATEX_solid_line(sx, ex, sy, ey);
- }
- #ifdef EEPIC
- else {
- EEPIC_move(sx, sy);
- EEPIC_vector(ex, ey);
- }
- #endif /* EEPIC */
- /* and then draw an arrowhead (a short vector) there */
- if (head)
- fprintf(gpoutfile, "\\put(%d,%d){\\vector(%d,%d){0}}\n",
- ex, ey,
- bestslope->dx * sign(ex - sx), bestslope->dy * sign(ey - sy));
- }
- TERM_PUBLIC void LATEX_put_text(x, y, str)
- unsigned int x, y; /* reference point of string */
- char str[]; /* the text */
- static char *justify[] =
- {"[l]", "", "[r]"};
- int flag, i;
- /* ignore empty strings */
- if (str[0] == NUL)
- return;
- for (flag = FALSE, i = 0; str[i] && !flag;)
- flag = (str[i++] == '\\') && (str[i++] == '\\');
- fprintf(gpoutfile, "\\put(%d,%d)", x, y);
- if ((str[0] == '{') || (str[0] == '[')) {
- fprintf(gpoutfile, "{\\makebox(0,0)%s}\n", str);
- } else if (flag)
- fprintf(gpoutfile, "{\\makebox(0,0)%s{\\shortstack{%s}}}\n",
- justify[latex_justify], str);
- else
- fprintf(gpoutfile, "{\\makebox(0,0)%s{%s}}\n",
- justify[latex_justify], str);
- TERM_PUBLIC int LATEX_justify_text(mode)
- enum JUSTIFY mode;
- latex_justify = mode;
- return (TRUE);
- TERM_PUBLIC int LATEX_text_angle(ang)
- int ang;
- /* we can't really write text vertically, but this will
- put the ylabel centred at the left of the plot, and
- then we'll make a \shortstack */
- latex_angle = ang;
- return (TRUE);
- TERM_PUBLIC void LATEX_reset()
- LATEX_posx = LATEX_posy = 0; /* current position */
- LATEX_moved = TRUE; /* pen is up after move */
- #ifdef EMTEX
- TERM_PUBLIC void EMTEX_init()
- emtex = TRUE;
- LATEX_posx = LATEX_posy = 0;
- fprintf(gpoutfile, "\
- %% GNUPLOT: LaTeX picture with emtex specials\n\
- \\setlength{\\unitlength}{%fpt}\n\
- \\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n",
- LATEX_UNIT);
- LATEX_linetype(-1);
- TERM_PUBLIC void EMTEX_reset()
- emtex = FALSE;
- LATEX_posx = LATEX_posy = 0;
- TERM_PUBLIC void EMTEX_text()
- fputs("\\end{picture}\n", gpoutfile);
- static void EMTEX_solid_line(x1, x2, y1, y2)
- int x1, x2, y1, y2;
- /* emtex special solid line */
- if (LATEX_moved)
- fprintf(gpoutfile, "\\put(%d,%d){\\special{em:moveto}}\n", x1, y1);
- if ((x1 != x2) || (y1 != y2))
- fprintf(gpoutfile, "\\put(%d,%d){\\special{em:lineto}}\n", x2, y2);
- LATEX_posx = x2;
- LATEX_posy = y2;
- LATEX_moved = FALSE;
- #endif /* EMTEX */
- #endif /* TERM_BODY */
- #endif /* TERM_PROTO_ONLY */
- #ifdef TERM_TABLE
- TERM_TABLE_START(latex_driver)
- "latex", "LaTeX picture environment",
- LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
- LATEX_VTIC, LATEX_HTIC, LATEX_options, LATEX_init, LATEX_reset,
- LATEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
- LATEX_linetype, LATEX_put_text, LATEX_text_angle,
- LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
- TERM_TABLE_END(latex_driver)
- #undef LAST_TERM
- #define LAST_TERM latex_driver
- #ifdef EMTEX
- TERM_TABLE_START(emtex_driver)
- "emtex", "LaTeX picture environment with emTeX specials",
- LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR,
- LATEX_VTIC, LATEX_HTIC, LATEX_options, EMTEX_init, EMTEX_reset,
- EMTEX_text, null_scale, LATEX_graphics, LATEX_move, LATEX_vector,
- LATEX_linetype, LATEX_put_text, LATEX_text_angle,
- LATEX_justify_text, LATEX_point, LATEX_arrow, set_font_null
- TERM_TABLE_END(emtex_driver)
- #undef LAST_TERM
- #define LAST_TERM emtex_driver
- #endif /* EMTEX */
- #endif /* TERM_TABLE */
- #ifdef TERM_HELP
- START_HELP(latex)
- "1 latex",
- "?commands set terminal emtex",
- "?set terminal emtex",
- "?set term emtex",
- "?terminal emtex",
- "?term emtex",
- "?latex",
- "?commands set terminal latex",
- "?set terminal latex",
- "?set term latex",
- "?terminal latex",
- "?term latex",
- "?emtex",
- " The `latex` and `emtex` drivers allow two options.",
- " Syntax:",
- " set terminal latex | emtex {courier | roman | default} {<fontsize>}",
- " `fontsize` may be any size you specify. The default is for the plot to",
- " inherit its font setting from the embedding document.",
- " Unless your driver is capable of building fonts at any size (e.g. dvips),",
- " stick to the standard 10, 11 and 12 point sizes.",
- " METAFONT users beware: METAFONT does not like odd sizes.",
- " All drivers for LaTeX offer a special way of controlling text positioning:",
- " If any text string begins with '{', you also need to include a '}' at the",
- " end of the text, and the whole text will be centered both horizontally and",
- " vertically. If the text string begins with '[', you need to follow this with",
- " a position specification (up to two out of t,b,l,r), ']{', the text itself,",
- " and finally '}'. The text itself may be anything LaTeX can typeset as an",
- " LR-box. '\\rule{}{}'s may help for best positioning.",
- " Points, among other things, are drawn using the LaTeX commands \"\\Diamond\" and",
- " \"\\Box\". These commands no longer belong to the LaTeX2e core; they are included",
- " in the latexsym package, which is part of the base distribution and thus part",
- " of any LaTeX implementation. Please do not forget to use this package.",
- " Points are drawn with the LaTex commands \\Diamond and \\Box. These",
- " commands do no longer belong to the LaTeX2e core, but are included in the",
- " latexsym-package in the base distribution, and are hence part of all LaTeX",
- " implementations. Please do not forget to use this package.",
- " Examples:",
- " About label positioning:",
- " Use gnuplot defaults (mostly sensible, but sometimes not really best):",
- " set title '\\LaTeX\\ -- $ \\gamma $'",
- " Force centering both horizontally and vertically:",
- " set label '{\\LaTeX\\ -- $ \\gamma $}' at 0,0",
- " Specify own positioning (top here):",
- " set xlabel '[t]{\\LaTeX\\ -- $ \\gamma $}'",
- " The other label -- account for long ticlabels:",
- " set ylabel '[r]{\\LaTeX\\ -- $ \\gamma $\\rule{7mm}{0pt}'"
- END_HELP(latex)
- #endif /* TERM_TABLE */
-